/**
 * Copyright [2019] [LiBo/Alex of copyright liboware@gmail.com ]
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.dess.stateful.egine.context;

import com.hyts.dess.stateful.egine.config.DataKeyEnum;
import com.hyts.dess.stateful.egine.core.StateMachine;
import com.hyts.dess.stateful.egine.core.impl.DefaultStateMachine;
import com.hyts.dess.stateful.egine.model.AccountUserModule;
import com.hyts.dess.stateful.egine.model.StateFlowModule;
import lombok.Getter;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @project-name:dess
 * @package-name:com.hyts.dess.stateful.egine.core
 * @author:LiBo/Alex
 * @create-date:2020-06-22 17:23
 * @copyright:libo-alex4java
 * @email:liboware@gmail.com
 * @description:
 */
public class StateMachineContext {

    /**
     * 状态机对象
     */
    @Getter
    private static final StateMachine STATE_MACHINE = new DefaultStateMachine();

    /** 用户全部信息缓存 */
    private static final Map<String, AccountUserModule> USER_ALL_DATA_MAP = new HashMap<>();

    /**
     * 获取相关的数据用户信息
     * @return
     */
    public static AccountUserModule get(String accessKey){
        //校验判断相关的accessKey键值对象参数信息
        if(!StringUtils.isEmpty(accessKey)){
            String key = String.format("%1$s:%2$s",DataKeyEnum.ACCOUNT_USER_DATA,accessKey);
            AccountUserModule accountUserModule = USER_ALL_DATA_MAP.get(key);
            //如果获取的用户信息对象为空!
            //TODO 获取相关的redis服务数据信息
            if(Objects.nonNull(accountUserModule)){
                return accountUserModule;
            }
            return null;
        }
        return null;
    }

    /**
     * 存储相关的accessKey对应的人员信息数据信息对象
     * @param accessKey
     * @param data
     * @return
     */
    public static boolean put(String accessKey, AccountUserModule data) {
//        String cacheKey = RedisCacheKey.ACK_LINK_DATA(accessKey);
//        RedisCache redisCache = RedisConfig.REDIS_CACHE;
//        boolean bl = redisCache.putCacheSave(cacheKey, data);
//        if (bl) {
//        }
//        return bl;
        String key = String.format("%1$s:%2$s",DataKeyEnum.ACCOUNT_USER_DATA,accessKey);
        return Objects.nonNull(USER_ALL_DATA_MAP.put(key, data));
    }

    /**
     * 更新用户状态流转模型配置
     * 既然是修改操作，调用方需先验证旧数据是否存在，防止NPE
     * 共用方法不包含这些具体的业务逻辑
     * @param data 全部数据
     * @param newConfig 新模型
     */
    public static boolean update(AccountUserModule data, StateFlowModule newConfig) {
        // 数据信息对象操作服务处理
        Objects.requireNonNull(newConfig,"状态流转配置对象不允许为空！");
        Objects.requireNonNull(data,"用户信息对象不允许为空！");
        // 更新相关的模板配置服务处理器功能实现
        Map<String, StateFlowModule> configs = data.getStateFlowConfigs();
        //先拿出旧的
        StateFlowModule oldConfig = configs.get(newConfig.getCode());
        //再进行更新
        configs.put(newConfig.getCode(), newConfig);
        boolean bl = put(data.getAccessKey(), data);
        //判断成功还是失败，执行相应逻辑
        if (bl) {
            //删除缓存的核心状态流转模型
            STATE_MACHINE.removeStateFlowModule(newConfig);
        } else {
            //还原数据
            configs.put(newConfig.getCode(), oldConfig);
        }
        return bl;
    }


    /**
     * 删除用户状态流转模型配置
     * @param data 模型集合
     * @param newConfig 删除的模型
     */
    public static boolean remove(AccountUserModule data, StateFlowModule newConfig) {
        Map<String, StateFlowModule> configs = data.getStateFlowConfigs();
        //先拿出旧的
        StateFlowModule oldConfig = configs.get(newConfig.getCode());
        //再进行删除
        configs.remove(newConfig.getCode());
        boolean bl = put(data.getAccessKey(), data);
        //判断成功还是失败，执行相应逻辑
        if (bl) {
            //删除缓存的核心状态流转模型
            STATE_MACHINE.removeStateFlowModule(newConfig);
        } else {
            //还原数据
            configs.put(newConfig.getCode(), oldConfig);
        }
        return bl;
    }


    /**
     * 获取状态流转配置，没有数据会直接抛出异常
     * @param accessKey
     * @param newConfig
     * @return
     */
    public static StateFlowModule getConfig(String accessKey, StateFlowModule newConfig) {
        AccountUserModule data = get(accessKey);
        Map<String, StateFlowModule> configs = data.getStateFlowConfigs();
        Objects.requireNonNull(configs,"未配置任何状态流转模型");
        StateFlowModule config = configs.get(newConfig.getCode());
        Objects.requireNonNull(configs,"找不到这个状态流转配置");
        return config;
    }

}
